package cn.tedu.sjmall.seckill.webapi.seckill.timer.job;

import cn.tedu.sjmall.seckill.webapi.seckill.mapper.SeckillSpuMapper;
import cn.tedu.sjmall.seckill.webapi.seckill.utils.RedisBloomUtils;
import cn.tedu.sjmall.seckill.webapi.seckill.utils.SeckillCacheUtils;
import lombok.extern.slf4j.Slf4j;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;

import java.time.LocalDate;


@Slf4j
public class SeckillBloomInitialJob implements Job {

    // 装配操作布隆过滤器的类
    @Autowired
    private RedisBloomUtils redisBloomUtils;
    // 装配能够查询秒杀spu表中所有spuId的mapper
    @Autowired
    private SeckillSpuMapper seckillSpuMapper;

    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        // 本方法的目标是将即将开始的秒杀包含的所有spuId保存到布隆过滤器
        // 在高读情况下防止缓存穿透,提高服务器效率
        // 布隆过滤器的key可以设计为当前日期,因为每天的商品不一样,
        // 而且出现过的日期不会再出现
        // spu:bloom:filter:2023-5-10
        String bloomDayKey=SeckillCacheUtils.getBloomFilterKey(LocalDate.now());
        // 判断Key是否已经存在(可选)
        // 从数据库中查询秒杀spu表中包含的所有spuId
        Long[] spuIds=seckillSpuMapper.findAllSeckillSpuIds();
        // 上面查询出的spuId数组是Long类型,但是布隆过滤器只能保存String[]
        // 所以要进行一个转换,将Long[]转换为String[]
        String[] spuIdsStr=new String[spuIds.length];
        // 循环遍历spuIds执行转换
        for (int i = 0; i < spuIds.length; i++) {
            spuIdsStr[i]=spuIds[i]+"";
        }
        // 转换成功后,就可以将包含所有spuId的String[],保存到布隆过滤器中了
        redisBloomUtils.bfmadd(bloomDayKey,spuIdsStr);
        log.info("布隆过滤器加载数据完成!");


    }
}
